package cnsatmsmart.automation.mmi.controller.Buffer;

import cnsatmsmart.automation.mmi.controller.Asterix21.CAsterix21;
import cnsatmsmart.automation.mmi.controller.Buffer.Asterix21Data;
import cnsatmsmart.automation.mmi.controller.Buffer.FlightList;
import cnsatmsmart.automation.mmi.controller.Buffer.Asterix21DataList;
import cnsatmsmart.automation.mmi.controller.Buffer.Flight;
import cnsatmsmart.automation.mmi.controller.IO.Painter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 * Merupakan kelas yang mengimplementasikan Runnable.
 * Objek dari kelas ini yang berjalan dalam thread akan mengambil data Asterix21 dari List Asterix21 kemudian memprosesnya dan memasukkannya ke List of Flight
 * @author SIK - PTIK, BPPT
 */
public class BufferThread implements Runnable{
	
    /* Atribut-atribut yang dimiliki oleh kelas BufferThread */
        private Asterix21Data Ax21Data;
        private Asterix21DataList Ax21DataList;
        private boolean ExitThread = false;
        private CAsterix21 Asterix21 = new CAsterix21();
        private FlightList FlightList;
        private File namaFile;
        private OutputStreamWriter out;
        private FileOutputStream fos;

        /**
         * Menunjukan mode sedang direkam atau tidak
         */
        public boolean playRec = false;
        
        /**
         * Constructor - user define constructor, no default constructor
         * @param flightList List dari data pesawat, yang merupakan data asterix yang telah diproses
         * @param ax21DataList List data asterix yang didapat dari server
         */
        public BufferThread(FlightList flightList, Asterix21DataList ax21DataList)
        {
            this.FlightList = flightList;
            this.Ax21DataList = ax21DataList;
        }

    /* Method-method untuk thread */
        /**
         * Keluar dari thread
         */
        public void Exit()
        {
            ExitThread = true;
        }

        public void run()
        {
            boolean saved = true;
            
            while (!ExitThread)
            {
                if (Ax21DataList.isEmpty())
                {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(BufferThread.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                else
                {
                    //No Reference, deep copy
                    Ax21Data = Ax21DataList.getAx21Data();

                    //Parsing DataBuffer dengan asterix21 parser
                    Asterix21.IsiData(Ax21Data.getDataBuffer(), Ax21Data.getBufferLen());
                    Asterix21.ProsesDataAsterix21();

                    try {
                        if (Asterix21.m_sTargetID != null)
                        {
                            //Data asterix yang telah diproses dimasukan ke dalam flightlist
                            FlightList.addData(Asterix21.m_strTargetAddress, Asterix21.m_sTargetID, Asterix21.m_strCountry, Asterix21.m_fFlightLevel, Asterix21.m_fGroundSpeed, Asterix21.m_fTrackAngle, Asterix21.m_fBarometricVerticalRate, Asterix21.m_fLatitudeInWGS, Asterix21.m_fLongitudeInWGS, Asterix21.m_sTimeOfDay);
                            String callsign = Asterix21.m_sTargetID;
                            Asterix21.m_sTargetID = null;

                            //Jika dalam mode merekam
                            if (playRec)
                            {
                                if (saved)
                                {
                                    try
                                    {
                                        String extension = getExtension(this.namaFile);
                                        if (extension == null || !extension.equals("txt"))
                                            {this.fos = new FileOutputStream(this.namaFile.getAbsolutePath() + ".txt");}
                                        else
                                            {this.fos = new FileOutputStream(this.namaFile);}
                                        this.out = new OutputStreamWriter(fos, Charset.forName("UTF-8"));
                                        this.out.write(writeHeader());
                                    } catch (FileNotFoundException ex) {
                                        Logger.getLogger(Painter.class.getName()).log(Level.SEVERE, null, ex);
                                    } catch (IOException ex) {
                                        Logger.getLogger(Painter.class.getName()).log(Level.SEVERE, null, ex);
                                    }
                                }
                                saved = false;
                                
                                if (out != null)
                                {
                                    try
                                    {
                                        this.out.write(record(Asterix21.m_strTargetAddress, callsign, Asterix21.m_strCountry, Asterix21.m_fFlightLevel, Asterix21.m_fGroundSpeed, Asterix21.m_fTrackAngle, Asterix21.m_fBarometricVerticalRate, Asterix21.m_fLatitudeInWGS, Asterix21.m_fLongitudeInWGS, Asterix21.m_sTimeOfDay,Flight.getTimeNow()));
                                    } catch (FileNotFoundException ex) {
                                        Logger.getLogger(Painter.class.getName()).log(Level.SEVERE, null, ex);
                                    } catch (IOException ex) {
                                        Logger.getLogger(Painter.class.getName()).log(Level.SEVERE, null, ex);
                                    }
                                }
                            }
                            else
                            {
                                if (!saved)
                                {
                                    saved = true;
                                    out.close();
                                    fos.close();
                                }
                            }
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(BufferThread.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }

        /**
         *
         * @param file
         */
        public void setNamaFile(File file)
        {
            this.namaFile = file;
        }

        private String writeHeader()
        {
            StringBuilder sb = new StringBuilder();
            sb.append("Code" + "\t");
            sb.append("Call Sign" + "\t");
            sb.append("Country"+ "\t");
            sb.append("Latitude" + "\t");
            sb.append("Longitude" + "\t");
            sb.append("Altitude" + "\t");
            sb.append("Vertical Rate" + "\t");
            sb.append("Track Angle" + "\t");
            sb.append("Ground Speed" + "\t");
            sb.append("Time" + "\t");
            sb.append("Time Of Day" + "\t\n");

            return sb.toString();
        }

        private String record(String code, String callSign, String country, float altitude, float groundspeed, float trackangle, float verticalrate, float latitude, float longitude, String timeOfDay, String time)
        {
            StringBuilder sb = new StringBuilder();
            sb.append(code + "\t");
            sb.append(callSign + "\t");
            sb.append(country+ "\t");
            sb.append(latitude + "\t");
            sb.append(longitude + "\t");
            sb.append(altitude + "\t");
            sb.append(verticalrate + "\t");
            sb.append(trackangle + "\t");
            sb.append(groundspeed + "\t");
            sb.append(time + "\t");
            sb.append(timeOfDay + "\t\n");

            return sb.toString();
        }

        /**
         * Fungsi untuk mendapatkan ekstensi dari suatu file
         * @param f File yang ingin diketahui ekstensinya
         * @return Ekstensi dari suatu file
         */
        public static String getExtension(File f)
        {
            String ext = null;
            String s = f.getName();
            int i = s.lastIndexOf('.');

            if (i > 0 &&  i < s.length() - 1) {
                ext = s.substring(i+1).toLowerCase();
            }
            return ext;
        }
}
